package com.zhb.cms.oauth.custom;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.util.StringUtils;

/**
 * 自定义scope权限的获取
 * @author itw_huomb
 *
 */
public class CustomOAuth2RequestFactory extends DefaultOAuth2RequestFactory
{

	private ClientDetailsService clientDetailsService;
	private JdbcTemplate jdbcTemplate;

	public CustomOAuth2RequestFactory(ClientDetailsService clientDetailsService, JdbcTemplate jdbcTemplate)
	{
		super(clientDetailsService);
		this.clientDetailsService = clientDetailsService;
		this.jdbcTemplate = jdbcTemplate;
	}
	/**
	 * 生成token
	 */
	@Override
	public TokenRequest createTokenRequest(Map<String, String> requestParameters, ClientDetails authenticatedClient)
	{
		String clientId = requestParameters.get(OAuth2Utils.CLIENT_ID);
		String grantType = requestParameters.get(OAuth2Utils.GRANT_TYPE);
		String username = requestParameters.get("username");
		//first clientScope
		Set<String> scopes = extractScopes(clientId);
		//second userScope
		if (!StringUtils.isEmpty(username))
		{
			List<Map<String, Object>> result = jdbcTemplate.queryForList(getScopeSql(), username);
			for (Map<String, Object> map : result)
			{
				Object scope = map.get("scope");
				if (scope != null)
				{
					scopes.add(scope.toString());
				}
			}
		}
		TokenRequest tokenRequest = new TokenRequest(requestParameters, clientId, scopes, grantType);

		return tokenRequest;
	}
	/**
	 * 获取scope的sql语句
	 */
	private String getScopeSql()
	{
		//@formatter:off
/*		String sql = "SELECT DISTINCT a.function_cd scope"+ 
						" FROM usr_role_function a"+ 
						" LEFT JOIN usr_user_role b ON a.role_cd=b.role_cd AND a.org_cd=b.org_cd"+ 
						" LEFT JOIN user_info c ON b.user_cd=c.user_cd"+ 
						" WHERE"+ 
						" a.deleted_flag='0'"+ 
						" AND b.deleted_flag='0'"+ 
						" AND a.function_cd is not null"+ 
						" AND c.username=?";*/
		String sql = "SELECT  CONCAT(c.org_cd,'_',c.function_cd) scope from oauth_user_role_function c "
				+ "where c.org_role_cd in ( SELECT  DISTINCT(org_role_cd)  FROM oauth_user_role a "
              +"RIGHT JOIN (SELECT user_cd,username FROM oauth_user_info "
             +"where username=?) b on a.user_cd=b.user_cd)";
		//@formatter:on}
		return sql;
	}

	/**
	 * extract ClientScopes
	 * @param clientId
	 */
	private Set<String> extractScopes(String clientId)
	{
		Set<String> scopes = new HashSet<String>();// OAuth2Utils.parseParameterList(requestParameters.get(OAuth2Utils.SCOPE));
		ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
		if (clientDetails.getScope() != null && clientDetails.getScope().size() > 0)
		{
			scopes = clientDetails.getScope();
		}
		return scopes;
	}
}
